home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * canvas -
- * Basic support for creation an manipulation of canvases.
- *
- * Paul Haeberli - 1991
- *
- * exports
- *
- int round(v)
- void initcanvas(c,xsize,ysize);
- canvas *newcanvas(xsize,ysize)
- canvas *imagetocanvas(name)
- canvas *crudeimagetocanvas(name)
- int canvastoimage(c,name)
- void freecanvas(c)
- canvas *clonecanvas(c)
- void canvasflushfunc(c,func)
- void flushcanvas(c)
- void canvascopy(c,cc)
- void touchcanvas(c)
- unsigned long samplecanvas(c,pos,dofilter)
- void markdirty(c,r,add)
- void clearcanvas(c)
- void framecanvas(c)
- void copyto(scan,dcan)
- canvas *subcanvas(c,x1,x2,y1,y2);
- void copycanvas(scan,srct,dcan,drct,filter)
- void printcanvas(c)
- *
- */
- #include "stdio.h"
- #include "canvas.h"
- #include "vect.h"
- #include "izoom.h"
- #include "math.h"
- #include "resource.h"
- #include "image.h"
-
- void canvascopy();
- void touchcanvas();
- void copycanvas();
-
- int round(v)
- float v;
- {
- return ffloor(v+0.499);
- }
-
- /*
- * canvas creation and free code
- *
- */
- void initcanvas(c,xsize,ysize)
- canvas *c;
- int xsize, ysize;
- {
- c->flushfunc = 0;
- c->xsize = xsize;
- c->ysize = ysize;
- c->strokeno = 0;
- c->area.xmin = 0;
- c->area.xmax = c->xsize-1;
- c->area.ymin = 0;
- c->area.ymax = c->ysize-1;
- c->undo = 0;
- }
-
- #define TAGLEN 5
-
- canvas *newcanvas(xsize,ysize)
- int xsize, ysize;
- {
- canvas *c;
- unsigned long *dptr;
-
- c = (canvas *)mymalloc(sizeof(canvas));
- initcanvas(c,xsize,ysize);
- c->data = (unsigned long *)mymalloc((xsize*ysize+TAGLEN)*sizeof(unsigned long));
- addlongimgtag(c->data,xsize,ysize);
- touchcanvas(c);
- return c;
- }
-
- canvas *imagetocanvas(name)
- char *name;
- {
- int xsize, ysize;
- canvas *c;
-
- sizeofimage(name,&xsize,&ysize);
- c = (canvas *)mymalloc(sizeof(canvas));
- initcanvas(c,xsize,ysize);
- c->data = (unsigned long *)longimagedata(name);
- touchcanvas(c);
- return c;
- }
-
- #define CRUDEPIX (100)
- static short *rbuf, *gbuf, *bbuf, *abuf;
- static unsigned long *sdata;
- static int *offset;
-
- canvas *crudeimagetocanvas(name)
- char *name;
- {
- int xsize, ysize, zsize, totpix;
- int cxsize, cysize, cxsize2, cysize2;
- int x, y, ix, iy;
- unsigned long *sptr;
- canvas *c;
- IMAGE *image;
-
- image = iopen(name,"r");
- if(!image) {
- fprintf(stderr,"can't open input file %s\n",name);
- exit(1);
- }
- xsize = image->xsize;
- ysize = image->ysize;
- zsize = image->zsize;
- totpix = xsize*ysize;
- cxsize = xsize*sqrt(CRUDEPIX/(float)totpix)+0.5;
- cysize = ysize*sqrt(CRUDEPIX/(float)totpix)+0.5;
- if(cxsize<1) cxsize = 1;
- if(cysize<1) cysize = 1;
- printf("csize %d %d\n",cxsize,cysize);
- cxsize2 = cxsize>>1;
- cysize2 = cysize>>1;
- c = (canvas *)mymalloc(sizeof(canvas));
- initcanvas(c,xsize,ysize);
- rbuf = (short *)bufalloc(rbuf,xsize*sizeof(short));
- gbuf = (short *)bufalloc(gbuf,xsize*sizeof(short));
- bbuf = (short *)bufalloc(bbuf,xsize*sizeof(short));
- abuf = (short *)bufalloc(abuf,xsize*sizeof(short));
- sdata = (unsigned long *)bufalloc(sdata,cxsize*cysize*sizeof(long));
- offset = (int *)bufalloc(offset,cxsize*sizeof(int));
- sptr = sdata;
- for(x=0; x<cxsize; x++)
- offset[x] = (x*xsize+cxsize2)/cxsize;
- for(y=0; y<cysize; y++) {
- iy = (y*ysize+cysize2)/cysize;
- getrow(image,rbuf,iy,0);
- if(zsize>=3) {
- getrow(image,gbuf,iy,1);
- getrow(image,bbuf,iy,2);
- if(zsize>3)
- getrow(image,abuf,iy,3);
- }
- if(zsize<3) {
- for(x=0; x<cxsize; x++) {
- ix = offset[x];
- *sptr++ = (0x10101*rbuf[ix])|0xff000000;
- }
- } else if(zsize == 3) {
- for(x=0; x<cxsize; x++) {
- ix = offset[x];
- *sptr++ = ((rbuf[ix]<<0)+(gbuf[ix]<<8)+
- (bbuf[ix]<<16))|0xff000000;
- }
- } else {
- for(x=0; x<cxsize; x++) {
- ix = offset[x];
- *sptr++ = ((rbuf[ix]<<0)+(gbuf[ix]<<8)+
- (bbuf[ix]<<16)+(abuf[ix]<<24));
- }
- }
- }
- iclose(image);
- c->data = (unsigned long *)malloc(xsize*ysize*sizeof(long));
- fastzoom(sdata,c->data,cxsize,cysize,xsize,ysize);
- touchcanvas(c);
- return c;
- }
-
- int canvastoimage(c,name)
- canvas *c;
- char *name;
- {
- return longstoimage(c->data,c->xsize,c->ysize,3,name);
- }
-
- void freecanvas(c)
- canvas *c;
- {
- if(c) {
- myfree(c->data);
- if(c->undo)
- freeundo(c);
- myfree(c);
-
- }
- }
-
- canvas *clonecanvas(c)
- canvas *c;
- {
- canvas *cc;
-
- cc = newcanvas(c->xsize,c->ysize);
- canvascopy(c,cc);
- cc->isdirty = c->isdirty;
- cc->dirt = c->dirt;
- cc->strokeno = c->strokeno;
- cc->undo = 0;
- return cc;
- }
-
- void canvasflushfunc(c,func)
- canvas *c;
- int (*func)();
- {
- c->flushfunc = func;
- }
-
- void flushcanvas(c)
- canvas *c;
- {
- if(c->isdirty) {
- if(c->flushfunc)
- c->flushfunc(c);
- c->isdirty = 0;
- }
- }
-
- void canvascopy(c,cc)
- canvas *c, *cc;
- {
- bcopy(c->data,cc->data,c->xsize*c->ysize*sizeof(unsigned long));
- }
-
- void touchcanvas(c)
- canvas *c;
- {
- c->isdirty = 1;
- c->dirt = c->area;
- }
-
- unsigned long samplecanvas(c,pos,dofilter)
- canvas *c;
- vect *pos;
- int dofilter;
- {
- int xpos, ypos;
-
- if(dofilter) {
- xpos = ((c->xsize-0.01)*pos->x)+qrand();
- ypos = ((c->ysize-0.01)*pos->y)+qrand();
- } else {
- xpos = ((c->xsize-0.01)*pos->x);
- ypos = ((c->ysize-0.01)*pos->y);
- }
- if(xpos<0)
- xpos = 0;
- if(ypos<0)
- ypos = 0;
- if(xpos>=c->xsize)
- xpos = c->xsize-1;
- if(ypos>=c->ysize)
- ypos = c->ysize-1;
- return c->data[c->xsize*ypos+xpos];
- }
-
- void markdirty(c,r,add)
- canvas *c;
- rct *r;
- int add;
- {
- if(r) {
- if(c->isdirty) {
- rctunion(&c->dirt,r,&c->dirt);
- } else {
- c->dirt = *r;
- }
- c->isdirty = 1;
- }
- c->strokeno+=add;
- }
-
- /*
- * drawing functions follow
- *
- */
- void clearcanvas(c)
- canvas *c;
- {
- int n;
- unsigned long *lptr, curc;
-
- saverect(c,&c->area);
- n = c->xsize*c->ysize;
- lptr = c->data;
- curc = getcurcolor();
- curc |= 0xff000000;
- while(n) {
- if(n>=8) {
- lptr[0] = curc;
- lptr[1] = curc;
- lptr[2] = curc;
- lptr[3] = curc;
- lptr[4] = curc;
- lptr[5] = curc;
- lptr[6] = curc;
- lptr[7] = curc;
- lptr += 8;
- n -= 8;
- } else {
- *lptr++ = curc;
- n--;
- }
- }
- touchcanvas(c);
- }
-
- framecanvas(c)
- canvas *c;
- {
- int n, xsize;
- unsigned long *lptr1, *lptr2, curc;
-
- saverect(c,&c->area);
- curc = getcurcolor();
- curc |= 0xff000000;
-
- xsize = c->xsize;
- lptr1 = c->data;
- lptr2 = c->data+(xsize*(c->ysize-1));
- n = xsize;
- while(n--) {
- *lptr1++ = curc;
- *lptr2++ = curc;
- }
- lptr1 = c->data;
- lptr2 = c->data+(xsize-1);
- n = c->ysize;
- while(n--) {
- *lptr1 = curc;
- *lptr2 = curc;
- lptr1 += xsize;
- lptr2 += xsize;
- }
- touchcanvas(c);
- }
-
- /*
- * canvas zoomed copy code follows
- *
- */
- static zoom *rz, *gz, *bz;
- static int sdx, sdy;
- static canvas *srccan;
- static rct *srcrct;
-
- static getr(buf,y)
- short *buf;
- int y;
- {
- unsigned char *ptr;
- int x;
-
- ptr = (unsigned char *)(srccan->data+
- ((srcrct->ymin+y)*srccan->xsize+srcrct->xmin));
- ptr = ptr+3;
- for(x=0; x<sdx; x++) {
- *buf++ = *ptr;
- ptr += 4;
- }
- }
-
- static getg(buf,y)
- short *buf;
- int y;
- {
- unsigned char *ptr;
- int x;
-
- ptr = (unsigned char *)(srccan->data+
- ((srcrct->ymin+y)*srccan->xsize+srcrct->xmin));
- ptr = ptr+2;
- for(x=0; x<sdx; x++) {
- *buf++ = *ptr;
- ptr += 4;
- }
- }
-
- static getb(buf,y)
- short *buf;
- int y;
- {
- unsigned char *ptr;
- int x;
-
- ptr = (unsigned char *)(srccan->data+
- ((srcrct->ymin+y)*srccan->xsize+srcrct->xmin));
- ptr = ptr+1;
- for(x=0; x<sdx; x++) {
- *buf++ = *ptr;
- ptr += 4;
- }
- }
-
- void copyto(scan,dcan)
- canvas *scan;
- canvas *dcan;
- {
- copycanvas(scan,&scan->area,dcan,&dcan->area,TRIANGLE);
- flushcanvas(dcan);
- }
-
- canvas *subcanvas(c,x1,x2,y1,y2)
- int x1, x2, y1, y2;
- {
- int dx, dy;
- canvas *subcan;
- rct srct;
-
- if(x2<x1 || y2<y1) {
- fprintf(stderr,"subcanvas: bad args\n");
- exit(1);
- }
- dx = x2-x1+1;
- dy = y2-y1+1;
-
- srct.xmin = x1;
- srct.xmax = x2;
- srct.ymin = y1;
- srct.ymax = y2;
-
- subcan = newcanvas(dx,dy);
- copycanvas(c,&srct,subcan,&subcan->area,IMPULSE);
- return subcan;
- }
-
- void copycanvas(scan,srct,dcan,drct,filter)
- canvas *scan;
- rct *srct;
- canvas *dcan;
- rct *drct;
- int filter;
- {
- int ddx, ddy;
- int sy, dy, lasty;
- unsigned long *sptr, *dptr;
- short *rs, *gs, *bs;
- short *rsp, *gsp, *bsp;
- int x, ncopy, basecopy;
- rct dirt;
-
- sdx = srct->xmax-srct->xmin+1;
- sdy = srct->ymax-srct->ymin+1;
- ddx = drct->xmax-drct->xmin+1;
- ddy = drct->ymax-drct->ymin+1;
- saverect(dcan,drct);
- if(sdx == ddx && sdy == ddy) { /* clips to dest canvas */
- ncopy = ddx;
- if(drct->xmin<0) {
- basecopy = (-drct->xmin);
- } else
- basecopy = 0;
- ncopy -= basecopy;
- if(drct->xmax>=dcan->xsize)
- ncopy -= ( drct->xmax-(dcan->xsize-1));
- if(ncopy>0) {
- sy = srct->ymin;
- dy = drct->ymin;
- sptr = scan->data+(sy*scan->xsize+srct->xmin);
- dptr = dcan->data+(dy*dcan->xsize+drct->xmin+basecopy);
- while(sy<=srct->ymax) {
- if(dy>=0 && dy<dcan->ysize)
- bcopy(sptr,dptr,ncopy*sizeof(long));
- sptr += scan->xsize;
- dptr += dcan->xsize;
- sy++;
- dy++;
- }
- }
- markdirty(dcan,drct,1);
- } else{
- srccan = scan;
- srcrct = srct;
- rz = newzoom(getr,sdx,sdy,ddx,ddy,filter,1.0);
- gz = newzoom(getg,sdx,sdy,ddx,ddy,filter,1.0);
- bz = newzoom(getb,sdx,sdy,ddx,ddy,filter,1.0);
- rs = (short *)mymalloc(ddx*sizeof(short));
- gs = (short *)mymalloc(ddx*sizeof(short));
- bs = (short *)mymalloc(ddx*sizeof(short));
- lasty = drct->ymin;
- dirt.xmin = drct->xmin;
- dirt.xmax = drct->xmax;
- for(dy=drct->ymin; dy<=drct->ymax; dy++) {
- getzoomrow(rz,rs,dy-drct->ymin);
- getzoomrow(gz,gs,dy-drct->ymin);
- getzoomrow(bz,bs,dy-drct->ymin);
- dptr = dcan->data+(dy*dcan->xsize+drct->xmin);
- rsp = rs;
- gsp = gs;
- bsp = bs;
- x = ddx;
- while(x) {
- if(x>=8) {
- dptr[0] = (rsp[0]<<0)+(gsp[0]<<8)+(bsp[0]<<16);
- dptr[1] = (rsp[1]<<0)+(gsp[1]<<8)+(bsp[1]<<16);
- dptr[2] = (rsp[2]<<0)+(gsp[2]<<8)+(bsp[2]<<16);
- dptr[3] = (rsp[3]<<0)+(gsp[3]<<8)+(bsp[3]<<16);
- dptr[4] = (rsp[4]<<0)+(gsp[4]<<8)+(bsp[4]<<16);
- dptr[5] = (rsp[5]<<0)+(gsp[5]<<8)+(bsp[5]<<16);
- dptr[6] = (rsp[6]<<0)+(gsp[6]<<8)+(bsp[6]<<16);
- dptr[7] = (rsp[7]<<0)+(gsp[7]<<8)+(bsp[7]<<16);
- dptr += 8;
- rsp += 8;
- gsp += 8;
- bsp += 8;
- x-=8;
- } else {
- *dptr++ = (*rsp<<0)+(*gsp<<8)+(*bsp<<16);
- rsp++;
- gsp++;
- bsp++;
- x--;
- }
- }
- if((dy-lasty)==10) {
- dirt.ymin = lasty;
- dirt.ymax = dy;
- markdirty(dcan,&dirt,1);
- flushcanvas(dcan);
- lasty = dy;
- }
- }
- dirt.ymin = lasty;
- dirt.ymax = dy-1;
- markdirty(dcan,&dirt,1);
- flushcanvas(dcan);
-
- freezoom(rz);
- freezoom(gz);
- freezoom(bz);
- myfree(rs);
- myfree(gs);
- myfree(bs);
- }
- }
-
- /*
- * canvas printing code
- *
- */
- void printcanvas(c)
- canvas *c;
- {
- mypercentdone(50.0);
- canvastoimage(c,"/usr/tmp/pr.rgb");
- system("printimage /usr/tmp/pr.rgb");
- system("rm /usr/tmp/pr.rgb");
- mypercentdone(100.0);
- }
-
-